package com.enation.app.javashop.core.distribution.service.impl;

import com.enation.app.javashop.core.base.model.enums.YesNoEnum;
import com.enation.app.javashop.core.distribution.model.dos.DistributionDO;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionDO;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionDetailDO;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionScheduleDO;
import com.enation.app.javashop.core.distribution.model.enums.DistributionMissionStatusEnums;
import com.enation.app.javashop.core.distribution.model.enums.RewardsTypeEnums;
import com.enation.app.javashop.core.distribution.model.vo.DistributionMissionVO;
import com.enation.app.javashop.core.distribution.model.vo.QueryDistributionMissionVO;
import com.enation.app.javashop.core.distribution.service.DistributionMissionDetailService;
import com.enation.app.javashop.core.distribution.service.DistributionMissionScheduleService;
import com.enation.app.javashop.core.distribution.service.DistributionMissionService;
import com.enation.app.javashop.core.member.model.dos.Member;
import com.enation.app.javashop.core.member.service.MemberManager;
import com.enation.app.javashop.core.shop.model.dos.Clerk;
import com.enation.app.javashop.core.shop.service.ClerkManager;
import com.enation.app.javashop.core.statistics.util.DateUtil;
import com.enation.app.javashop.core.trade.order.model.enums.YesOrNoEnums;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.exception.SystemErrorCodeV1;
import com.enation.app.javashop.framework.security.model.Seller;
import com.enation.app.javashop.framework.util.BeanUtil;
import com.enation.app.javashop.framework.util.SqlSplicingUtil;
import com.enation.app.javashop.framework.util.StringUtil;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 王志杨
 * @since 2021/1/22 17:21
 * 团长任务service实现
 */
@Service
public class DistributionMissionServiceImpl implements DistributionMissionService {

    @Autowired
    @Qualifier("distributionDaoSupport")
    private DaoSupport daoSupport;
    @Autowired
    private ClerkManager clerkManager;
    @Autowired
    private MemberManager memberManager;
    @Autowired
    private DistributionMissionDetailService distributionMissionDetailService;
    @Autowired
    private DistributionMissionScheduleService distributionMissionScheduleService;


    @Override
    public void insertDistributionMission(DistributionMissionDO distributionMissionDO, Seller seller) {

        long nowTime = DateUtil.getDateline();

        //如果活动起始时间小于现在时间
        if (distributionMissionDO.getStartTime() < nowTime) {
            throw new ServiceException(SystemErrorCodeV1.INVALID_REQUEST_PARAMETER, "活动起始时间必须大于当前时间");
        }

        // 开始时间不能大于结束时间
        if (distributionMissionDO.getStartTime() > distributionMissionDO.getEndTime()) {
            throw new ServiceException(SystemErrorCodeV1.INVALID_REQUEST_PARAMETER, "活动起始时间不能大于活动结束时间");
        }

        // 设置创建人和创建时间
        distributionMissionDO.setCreateTime(DateUtil.getDateline());
        Clerk clerk = clerkManager.getClerkByMemberId(seller.getUid());
        if (!ObjectUtils.isEmpty(clerk)) {
            distributionMissionDO.setCreateName(clerk.getClerkName());
        }

        // 设置店铺ID和店铺名称
        distributionMissionDO.setSellerId(seller.getSellerId());
        distributionMissionDO.setSellerName(seller.getSellerName());

        daoSupport.insert("es_distribution_mission", distributionMissionDO);
    }

    @Override
    public void updateDistributionMission(DistributionMissionDO distributionMissionDO, Seller seller) {
        long nowTime = DateUtil.getDateline();

        //如果活动起始时间小于现在时间
        if (distributionMissionDO.getStartTime() < nowTime) {
            throw new ServiceException(SystemErrorCodeV1.INVALID_REQUEST_PARAMETER, "活动起始时间必须大于当前时间");
        }

        // 开始时间不能大于结束时间
        if (distributionMissionDO.getStartTime() > distributionMissionDO.getEndTime()) {
            throw new ServiceException(SystemErrorCodeV1.INVALID_REQUEST_PARAMETER, "活动起始时间不能大于活动结束时间");
        }

        // 设置修改人和修改时间
        distributionMissionDO.setUpdateTime(DateUtil.getDateline());
        Clerk clerk = clerkManager.getClerkByMemberId(seller.getUid());
        if (!ObjectUtils.isEmpty(clerk)) {
            distributionMissionDO.setUpdateName(clerk.getClerkName());
        }

        daoSupport.update(distributionMissionDO, distributionMissionDO.getId());
    }

    @Override
    @Transactional(value = "distributionTransactionManager", rollbackFor = Exception.class)
    public void deleteDistributionMission(Integer missionId, Seller seller) {
        // 删除任务
        daoSupport.execute("update es_distribution_mission set is_delete=1 where id=? and seller_id=?", missionId, seller.getSellerId());

        // 删除任务明细
        distributionMissionDetailService.deleteDistributionMissionDetailByMissionId(missionId);

        // 删除团长任务进度明细
        distributionMissionScheduleService.deleteDistributionMissionScheduleByMissionId(missionId);
    }

    @Override
    public Page<DistributionMissionVO> queryDistributionMissionList(QueryDistributionMissionVO queryDistributionMissionVO) {

        // 1.组装查询条件参数
        StringBuilder sql = new StringBuilder("select * from es_distribution_mission");

        List<Object> termList = new ArrayList<>();
        List<String> sqlSplit = new ArrayList<>();

        Integer sellerId = queryDistributionMissionVO.getSellerId();
        if (sellerId != null) {
            sqlSplit.add(" seller_id=? ");
            termList.add(sellerId);
        }

        if (queryDistributionMissionVO.getMissionStatus() != null) {
            sqlSplit.add(" mission_status=? ");
            termList.add(queryDistributionMissionVO.getMissionStatus());
        }

        sqlSplit.add(" is_delete=? ");
        termList.add(YesNoEnum.NO.getIndex());

        // 团长任务名称查询
        String missionName = queryDistributionMissionVO.getMissionName();
        if (StringUtil.notEmpty(missionName)) {
            sqlSplit.add(" mission_name like ? ");
            termList.add("%" + missionName + "%");
        }

        // 奖励类型查询
        Integer rewardsType = queryDistributionMissionVO.getRewardsType();
        if (!ObjectUtils.isEmpty(rewardsType)) {
            sqlSplit.add(" rewards_type=? ");
            termList.add(rewardsType);
        }

        // 按时间查询
        Long startTime = queryDistributionMissionVO.getStartTime();
        if (!ObjectUtils.isEmpty(startTime)) {
            sqlSplit.add(" start_time >= ? ");
            termList.add(startTime);
        }
        Long endTime = queryDistributionMissionVO.getEndTime();
        if (!ObjectUtils.isEmpty(endTime)) {
            sqlSplit.add(" end_time <= ? ");
            termList.add(endTime);
        }

        // 2.对sql条件语句进行拼接并查询
        String sqlSplicing = SqlSplicingUtil.sqlSplicing(sqlSplit);
        if (StringUtil.notEmpty(sqlSplicing)) {
            sql.append(sqlSplicing);
        }
        sql.append(" order by create_time desc");
        Page page = this.daoSupport.queryForPage(sql.toString(), queryDistributionMissionVO.getPageNo(), queryDistributionMissionVO.getPageSize(),
                DistributionMissionDO.class, termList.toArray());

        // 3.DO转VO，枚举转换文本
        List<DistributionMissionVO> distributionMissionVOList = new ArrayList<>();
        List<DistributionMissionDO> data = page.getData();
        for (DistributionMissionDO distributionMissionDO : data) {
            DistributionMissionVO distributionMissionVO = new DistributionMissionVO();
            BeanUtil.copyProperties(distributionMissionDO, distributionMissionVO);
            Integer missionStatusIndex = distributionMissionVO.getMissionStatus();
            distributionMissionVO.setMissionStatusText(DistributionMissionStatusEnums.getTextByIndex(missionStatusIndex));
            Integer rewardsTypeIndex = distributionMissionVO.getRewardsType();
            distributionMissionVO.setRewardsTypeText(RewardsTypeEnums.getTextByIndex(rewardsTypeIndex));
            distributionMissionVOList.add(distributionMissionVO);
        }

        // 4.组装page对象返回
        page.setData(distributionMissionVOList);
        return page;
    }

    @Override
    public DistributionMissionDO getDistributionMissionByMissionId(Integer missionId) {
        return daoSupport.queryForObject(DistributionMissionDO.class, missionId);
    }

    @Override
    public void onOffLine(Integer missionId, Integer missionStatus) {
        // 如果是上线任务，判断时候当前店铺已经有已上线的团长任务
        if (DistributionMissionStatusEnums.ONLINE.getIndex() == missionStatus) {
            Seller seller = UserContext.getSeller();
            List<DistributionMissionDO> missionDOList = this.getDistributionMissionBySellerId(seller.getSellerId());
            if (!CollectionUtils.isEmpty(missionDOList)) {
                List<String> names = missionDOList.stream().map(DistributionMissionDO::getMissionName).collect(Collectors.toList());
                throw new ServiceException("500", "团长任务【" + StringUtil.listToString(names, "，") + "】已上线，同时只能有一个团长任务在线！");
            }
        }


        DistributionMissionDO distributionMissionDO = getDistributionMissionByMissionId(missionId);
        distributionMissionDO.setMissionStatus(missionStatus);
        daoSupport.update(distributionMissionDO, missionId);
    }

    /**
     * 查询团长任务进度
     */
    @Override
    public Map queryMissionIndex(Integer memberId) {
        Map<String, Object> resultMap = new HashMap<>();

        // 查询团长
        Member member = memberManager.getMemberById(memberId);

        // 查询最新的团长任务活动
        DistributionMissionVO distributionMission = queryLatestMission();

        if (distributionMission != null) {
            resultMap.put("mission", distributionMission);

            // 计算累计奖励金额
            BigDecimal totalReward = BigDecimal.ZERO;

            Integer missionId = distributionMission.getId();
            // 查询任务明细
            List<DistributionMissionDetailDO> distributionMissionDetailList = distributionMissionDetailService.queryDistributionMissionDetailByMissionId(missionId);

            for (DistributionMissionDetailDO distributionMissionDetailDO : distributionMissionDetailList) {
                Integer missionType = distributionMissionDetailDO.getMissionType();
                Integer missionDetailId = distributionMissionDetailDO.getId();
                if (missionType == 0) {
                    // 获取今天日期
                    String todayDate = DateUtil.toString(new Date(), "MM-dd");
                    // 查询每日任务 如果没有就新建
                    DistributionMissionScheduleDO dayMissionScheduleDO = distributionMissionScheduleService.queryDistributionMissionSchedule(memberId, missionId, missionDetailId, missionType, todayDate);
                    if (dayMissionScheduleDO == null) {
                        dayMissionScheduleDO = distributionMissionScheduleService.createMissionSchedule(member, distributionMission, distributionMissionDetailDO, todayDate);
                    }

                    totalReward = totalReward.add(dayMissionScheduleDO.getTotalReward());

                    resultMap.put("dayMissionDetail", distributionMissionDetailDO);
                    resultMap.put("dayMissionSchedule", dayMissionScheduleDO);

                    resultMap.put("dayCountdownTime", DateUtil.getTomorrowZero() - DateUtil.getDateline());
                } else {
                    // 获取本月
                    String thisMonth = DateUtil.toString(new Date(), "yy-MM");
                    // 查询每月任务 如果没有就新建
                    DistributionMissionScheduleDO monthMissionScheduleDO = distributionMissionScheduleService.queryDistributionMissionSchedule(memberId, missionId, missionDetailId, missionType, thisMonth);
                    if (monthMissionScheduleDO == null) {
                        monthMissionScheduleDO = distributionMissionScheduleService.createMissionSchedule(member, distributionMission, distributionMissionDetailDO, thisMonth);
                    }

                    totalReward = totalReward.add(monthMissionScheduleDO.getTotalReward());

                    resultMap.put("monthMissionDetail", distributionMissionDetailDO);
                    resultMap.put("monthMissionSchedule", monthMissionScheduleDO);

                    // 距离任务结束时间
                    Long endTime = distributionMission.getEndTime();
                    if (endTime != null) {
                        resultMap.put("monthCountdownTime", distributionMission.getEndTime() - DateUtil.getDateline());
                    }
                }
            }

            resultMap.put("totalReward", totalReward);
        }
        return resultMap;
    }

    @Override
    public List<DistributionMissionDO> getDistributionMissionBySellerId(Integer sellerId) {
        String sql = "select * from es_distribution_mission where seller_id=? and mission_status=? and is_delete=?";
        List<DistributionMissionDO> missionDOList = daoSupport.queryForList(sql, DistributionMissionDO.class, sellerId, DistributionMissionStatusEnums.ONLINE.getIndex(), YesOrNoEnums.NO.getIndex());
        return daoSupport.queryForList(sql, DistributionMissionDO.class, sellerId, DistributionMissionStatusEnums.ONLINE.getIndex(), YesOrNoEnums.NO.getIndex());
    }


    /**
     * 查询最新的活动
     */
    @Override
    public DistributionMissionVO queryLatestMission() {
        Long time = DateUtil.getDateline();

        String sql = "select * from es_distribution_mission where is_delete = ? and mission_status = ? and start_time <= ? and end_time >= ? order by create_time desc";

        List<DistributionMissionDO> missionList = this.daoSupport.queryForList(sql, DistributionMissionDO.class,
                YesOrNoEnums.NO.getIndex(),DistributionMissionStatusEnums.ONLINE.getIndex(),time, time);
        if (!CollectionUtils.isEmpty(missionList)) {
            DistributionMissionDO distributionMissionDO = missionList.get(0);
            DistributionMissionVO distributionMissionVO = new DistributionMissionVO();
            BeanUtil.copyProperties(distributionMissionDO, distributionMissionVO);
            Integer missionStatusIndex = distributionMissionVO.getMissionStatus();
            distributionMissionVO.setMissionStatusText(DistributionMissionStatusEnums.getTextByIndex(missionStatusIndex));
            Integer rewardsTypeIndex = distributionMissionVO.getRewardsType();
            distributionMissionVO.setRewardsTypeText(RewardsTypeEnums.getTextByIndex(rewardsTypeIndex));
            return distributionMissionVO;
        }

        return null;
    }
}
